#include "built_effect.h"
#include "usb_config.h"

//#include "w25n01gv.h"
#include "flashDriver.h"
//uint32_t flashID = 0;
//uint8_t protReg;
//uint8_t confReg;
//uint8_t statReg;

#define LED_PIN LL_GPIO_PIN_15
#define LED_GPIO_PORT GPIOA
#define LED_GPIO_CLK_ENABLE() LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA)
#define LED_GPIO_CLK_DISABLE() LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOA)

int led_init()
{
    /* Enable the GPIO_LED Clock */
    LED_GPIO_CLK_ENABLE();
    /* Configure the GPIO_LED pin */
    LL_GPIO_SetPinMode(LED_GPIO_PORT, LED_PIN, LL_GPIO_MODE_OUTPUT);
    LL_GPIO_SetPinOutputType(LED_GPIO_PORT, LED_PIN, LL_GPIO_OUTPUT_PUSHPULL);
    LL_GPIO_SetPinSpeed(LED_GPIO_PORT, LED_PIN, LL_GPIO_SPEED_FREQ_LOW);
    LL_GPIO_SetPinPull(LED_GPIO_PORT, LED_PIN, LL_GPIO_PULL_NO);
    LL_GPIO_SetOutputPin(LED_GPIO_PORT, LED_PIN);
    return 0;
}
INIT_BOARD_EXPORT(led_init);



void test_spi_nand_flash(void)
{
    uint8_t test_buffer[256];
    uint8_t read_buffer[256];
    uint32_t i;
    uint32_t flash_id;
    
    // 初始化SPI和Flash
    rt_kprintf("Initializing SPI and Flash...\n");
    initFlash();
    
    // 测试1: 读取Flash ID
    rt_kprintf("\n=== Test 1: Read Flash ID ===\n");
    flash_id = getFlashID();
    rt_kprintf("Flash ID: 0x%06lX\n", flash_id & 0xFFFFFF);
    if((flash_id & 0xFFFFFF) == 0xEFAA21) {
        rt_kprintf("Flash ID verification PASSED (W25N01GV detected)\n");
    } else {
        rt_kprintf("Flash ID verification FAILED (Expected 0xEFAA21)\n");
        return;
    }
    
    // 测试2: 状态寄存器读取
    rt_kprintf("\n=== Test 2: Read Status Registers ===\n");
    rt_kprintf("Status Register 1: 0x%02X\n", checkStatusReg(STATUS_REG_ADDRESS));
    rt_kprintf("Configuration Register: 0x%02X\n", checkStatusReg(CONF_REG_ADDRESS));
    rt_kprintf("Protection Register: 0x%02X\n", checkStatusReg(PROT_REG_ADDRESS));
    
    // 测试3: 块擦除测试 (使用最后一个块，避免损坏重要数据)
    uint32_t test_block = 1023; // 最后一个块
    uint32_t test_addr = test_block * NAND_PAGES_PER_BLOCK * NAND_FLASH_PAGE_SIZE;
    
    rt_kprintf("\n=== Test 3: Block Erase Test ===\n");
    rt_kprintf("Erasing block %lu at address 0x%08lX...\n", test_block, test_addr);
    
//    if(blockErase(test_addr) == HAL_OK) {
//        rt_kprintf("Block erase command sent successfully\n");
//    } else {
//        rt_kprintf("Block erase FAILED\n");
//        return;
//    }
    blockErase(test_addr);
    // 等待擦除完成
    waitForNotBusy();
    rt_kprintf("Erase operation completed\n");
    
    // 检查状态寄存器
    uint8_t status = checkStatusReg(STATUS_REG_ADDRESS);
    if(status & 0x20) {
        rt_kprintf("Erase FAILED (Status Reg: 0x%02X)\n", status);
    } else {
        rt_kprintf("Erase SUCCESS (Status Reg: 0x%02X)\n", status);
    }
    
    // 测试4: 页编程和读取测试
    rt_kprintf("\n=== Test 4: Page Program and Read Test ===\n");
    
    // 准备测试数据 (模式数据)
    for(i = 0; i < sizeof(test_buffer); i++) {
        test_buffer[i] = i;
    }
    
    // 写入测试页 (使用擦除过的块的第一个页)
    uint32_t test_page = test_block * NAND_PAGES_PER_BLOCK;
    rt_kprintf("Writing test pattern to page %lu...\n", test_page);
    
    if(writeFlashPage(test_buffer, test_page * NAND_FLASH_PAGE_SIZE, sizeof(test_buffer))) {
        rt_kprintf("Page program FAILED\n");
        return;
    }
    
    // 等待写入完成
    waitForNotBusy();
    status = checkStatusReg(STATUS_REG_ADDRESS);
    if(status & 0x10) {
        rt_kprintf("Write FAILED (Status Reg: 0x%02X)\n", status);
    } else {
        rt_kprintf("Write SUCCESS (Status Reg: 0x%02X)\n", status);
    }
    
    // 读取回数据
    rt_kprintf("Reading back data from page %lu...\n", test_page);
    if(readFlashPage(read_buffer, test_page * NAND_FLASH_PAGE_SIZE, sizeof(read_buffer))) {
        rt_kprintf("Page read FAILED\n");
        return;
    }
    
    // 验证数据
    uint8_t errors = 0;
    for(i = 0; i < sizeof(read_buffer); i++) {
        if(read_buffer[i] != test_buffer[i]) {
            errors++;
            if(errors < 10) { // 只打印前10个错误
                rt_kprintf("Data mismatch at offset %lu: wrote 0x%02X, read 0x%02X\n", 
                          i, test_buffer[i], read_buffer[i]);
            }
        }
    }
    
    if(errors == 0) {
        rt_kprintf("Data verification PASSED - all %d bytes matched\n", sizeof(read_buffer));
    } else {
        rt_kprintf("Data verification FAILED - %d errors found\n", errors);
    }
    
    rt_kprintf("\n=== SPI NAND Flash Test Completed ===\n");
}



int main(void)
{
//    if (FlashInit() == 0)
//        BadBlockManage();
//    initFlash();
//    rt_kprintf("Flash ID: 0x%06X\n", flashID);

//    test_spi_nand_flash();
    
    while (1)
    {
        LL_GPIO_TogglePin(LED_GPIO_PORT, LED_PIN);    
        ws2812_test();
//        rt_kprintf("test\n");
        rt_thread_mdelay(500);
        
    }
}

int usbd_init(void)
{
    /* usb select the HSI48M clock */
    LL_RCC_HSI48_Enable();
    LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_HSI48);
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USB);

    msc_ram_init();
   
    /* Enable USB interrupt */
    NVIC_EnableIRQ(USBD_IRQn);
    NVIC_SetPriority(USBD_IRQn, 0);

    return 0;
}
INIT_BOARD_EXPORT(usbd_init);

/**
 * @brief  Error handling function
 * @param  None
 * @retval None
 */
void APP_ErrorHandler(void)
{
    /* Infinite loop */
    while (1)
    {
    }
}

#ifdef USE_FULL_ASSERT
/**
 * @brief  Reports the name of the source file and the source line number
 *         where the assert_param error has occurred.
 * @param  file：Pointer to the source file name
 * @param  line：assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* User can add His own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* Infinite loop */
    while (1)
    {
    }
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT Puya *****END OF FILE******************/
